#import "BitlyLink.h"

// NOTE: This is a very simple class that can fetch an xml feed of videos from
// YouTube and parse it into BitlyLink objects. This is meant to be light 
// and simple for learning purposes; a real project should use the full-featured
// GData Objective-C API: http://code.google.com/p/gdata-objectivec-client/

//static NSString* const kPlayerURLQuery = @"./media:group/media:player/@url";
//static NSString* const kThumbURLQuery = @"./media:group/media:thumbnail/@url"; 
static NSString* const kPlayerURLQuery = @"//longUrl";
static NSString* const kThumbURLQuery = @"//thumbnail/medium"; 

@implementation BitlyLink

+ (id)videoWithXMLNode:(NSXMLNode *)node {
  return [[[BitlyLink alloc] initWithXMLNode:node] autorelease];
}

- (id)initWithXMLNode:(NSXMLNode *)node {
  if ((self = [super init])) {
    xmlNode_ = [node retain];
  }
  return self;
}
- (void)dealloc {
  [xmlNode_ release];
  [super dealloc];
}

- (NSURL *)URLFromQuery:(NSString *)query {
  NSError* error;
  NSArray* nodes = [xmlNode_ nodesForXPath:query error:&error];
  if (nodes != nil && [nodes count] > 0) {
    NSString* urlStr = [[nodes lastObject] stringValue];
    if (urlStr != nil) {
      return [NSURL URLWithString:urlStr];
    }
  }
  return nil;
}

- (NSURL *)thumbnailURL {
  return [self URLFromQuery:kThumbURLQuery];
}
- (NSURL *)playerURL {
  return [self URLFromQuery:kPlayerURLQuery];
}
- (NSData *)xmlData {
  NSString* xml = [xmlNode_ XMLStringWithOptions:NSXMLNodePrettyPrint];
  return [xml dataUsingEncoding:NSUTF8StringEncoding];
}

// See: http://code.google.com/apis/youtube/overview.html
// NOTE: Ideally the caller of this method would handle failure and handle dialog
// boxes, exiting from the app, etc. For the sake of the bitlyfs tutorial, this is
// done here to minimize changes needed to the bitlyfs_Controller class.
+ (NSDictionary *)fetchRecentLinks:(NSString *)user {
	CFUUIDRef	uuidObj = CFUUIDCreate(nil);//create a new UUID
	NSString	*uuidString = (NSString*)CFUUIDCreateString(nil, uuidObj);	
	NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@.bit.ly/recent.rss.xml?%@", user, uuidString]];
	CFRelease(uuidObj);

	NSURLRequest* request = [NSURLRequest requestWithURL:url];
	NSURLResponse* response = nil;
	NSError* error = nil;
	NSData* data = [NSURLConnection sendSynchronousRequest:request 
										 returningResponse:&response
													 error:&error];
	if (data == nil) {
		NSRunAlertPanel(@"bitlyfs Error", @"Unable to download feed.",
						@"Ack", nil, nil);
		return(nil);
	}
	NSXMLDocument* doc = [[NSXMLDocument alloc] initWithData:data 
													 options:0 
													   error:&error];  
	NSArray* xmlEntries = [[doc rootElement] nodesForXPath:@"//item" 
													 error:&error];
	if ([xmlEntries count] == 0) {
		NSRunAlertPanel(@"bitlyfs Error", @"Feed has zero entries.  Bummer.",
						@"Ack", nil, nil);
		return(nil);
	}
	
	NSMutableDictionary* videos = [NSMutableDictionary dictionary];
	for (int i = 0; i < [xmlEntries count]; ++i) {
		NSXMLNode* node	= [xmlEntries objectAtIndex:i];
		NSArray* nodes	= [node nodesForXPath:@"./link" error:&error];
		NSString* link	= [[nodes objectAtIndex:0] stringValue];
		NSArray* chunks	= [link componentsSeparatedByString: @"/"];
		NSString* hash	= [chunks objectAtIndex:3];
		nodes			= [node nodesForXPath:@"./title" error:&error];
		NSString* title = [[nodes objectAtIndex:0] stringValue];
		
		NSLog(@"%d Link %@", i, link);

		NSMutableString* name = [NSMutableString stringWithFormat:@"%@ - %@.webloc", title, hash];
		NSMutableString* apiurl = [NSMutableString stringWithFormat:@"http://api.bit.ly/info?version=2.0.1&login=bitlyfs&apiKey=R_eb40f052ad48f115dc55620b963ac27f&format=xml&hash=%@", hash];
		NSURL* infourl = [NSURL URLWithString:apiurl];
		NSURLRequest* request2 = [NSURLRequest requestWithURL:infourl];
		NSURLResponse* response2 = nil;
		NSError* error2 = nil;
		NSData* data2 = [NSURLConnection sendSynchronousRequest:request2 
											 returningResponse:&response2
														 error:&error2];
	    NSXMLDocument* doc2 = [[NSXMLDocument alloc] initWithData:data2 
														 options:0 
														   error:&error2];  
		if (doc2 == nil) continue;
		BitlyLink* video = [BitlyLink videoWithXMLNode:[doc2 rootElement]];
		[videos setObject:video forKey:name];
	}
	return videos;
}

@end
